package thread;

import java.util.Arrays;
import java.util.Optional;
import java.util.OptionalInt;

/**
 * demo06
 * 生产者消费者问题
 * 管程法
 *
 * @author dingwen
 * @date 2021/09/06
 */
public class Demo06 {
    public static void main(String[] args) {
        // 仓库
        Store store = new Store();
        // 生产者
        Producer producer = new Producer(store);
        // 消费者
        Customer customer = new Customer(store);
        new Thread(producer).start();
        new Thread(customer).start();
    }
}


/**
 * 产品
 * 鸡
 *
 * @author dingwen
 * @date 2021/09/06
 */
class Chicken {
    /**
     * 产品id
     */
    private int  id;

    public Chicken(int  id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }
}


/**
 * 商店(仓库)
 *
 * @author dingwen
 * @date 2021/09/06
 */
class Store {
    Chicken[] chickenArr = new Chicken[10];
    int count = 0;

    /**
     * 生产者生产产品放入仓库
     *
     * @param chicken 鸡
     */
    public synchronized void push(Chicken chicken) {
        if (count == chickenArr.length) {
            // 仓库已满  等待消费
            // 生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        chickenArr[count] = chicken;
        count++;

        // 已经有产品通知消费者消费
        this.notifyAll();
    }


    /**
     * 消费者消费
     *
     * @return {@link Chicken}
     */
    public synchronized Chicken pop(){
        if(this.count == 0){
            // 没有产品了 等待生产着生产
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 消费了产品通知生产者生产
        this.notifyAll();
        // 数组下标从零开始
        return chickenArr[--this.count];
    }

}


/**
 * 生产商
 *
 * @author dingwen
 * @date 2021/09/06
 */
class Producer implements Runnable{
    /**
     * 仓库
     */
    public Store store;

    public Producer(Store store) {
        this.store = store;
    }


    /**
     * 生产产品
     */
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            store.push(new Chicken(i));
            System.out.println("生产者生产了第" + i + "只鸡");
        }
    }
}

/**
 * 消费者
 *
 * @author dingwen
 * @date 2021/09/06
 */
class Customer implements Runnable{
    /**
     * 仓库
     */
    public Store store;

    public Customer(Store store) {
        this.store = store;
    }


    /**
     * 消费者消费
     */
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            System.out.println("消费者消费了第" + (store.pop().getId()) + "鸡");
        }
    }
}